package station.GUI;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;

import nxt.commandReference.StationCommands;
import station.Bluetooth.BluetoothManager;
import station.VisualComponents.CameraConnectionListener;
import station.VisualComponents.CameraConnectionMakerThread;


public class MainForm {

	private JFrame frmRoboprojectRemote;
	private BluetoothManager btm = new BluetoothManager();
	private CameraConnectionMakerThread ccmt = new CameraConnectionMakerThread();
	public CameraConnectionListener camConnListener;
	public JLabel lblBatteryvar;
	public JLabel lblSpeedvar;
	public JLabel lblDistancevar;
	public JLabel lblConnectedCam;
	public JSlider sliderLightIntensity;
	public JSlider sliderSignalStrenght;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainForm window = new MainForm();
					window.frmRoboprojectRemote.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public MainForm() {
		initialize();
		btm.setGUIMainForm(this);
		KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
		RoboKeyDispatcher rkd = new RoboKeyDispatcher();
		rkd.setBTM(btm);
	    manager.addKeyEventDispatcher(rkd);
	    ccmt.setMainForm(this);
	    ccmt.start();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmRoboprojectRemote = new JFrame();
		frmRoboprojectRemote.setTitle("RoboProject Remote");
		frmRoboprojectRemote.setBounds(100, 100, 1024, 610);
		frmRoboprojectRemote.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JPanel panel = new JPanel();
		
		frmRoboprojectRemote.getContentPane().add(panel);
		panel.setLayout(null);
		
		final JList listBTDevices = new JList();
		listBTDevices.setBorder(new LineBorder(new Color(0, 0, 0)));
		listBTDevices.setBounds(10, 36, 227, 141);
		panel.add(listBTDevices);
		
		JLabel lblBTDevices = new JLabel("Bluetoothdevices in range (connect to NXT):");
		lblBTDevices.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblBTDevices.setBounds(10, 11, 227, 14);
		panel.add(lblBTDevices);
		
		JButton btnRefreshBTD = new JButton("Refresh");
		btnRefreshBTD.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				btm.refreshDevices();
				DefaultListModel lm = new DefaultListModel();
				int index=0;
				for (String s : btm.getDeviceNames()) {
					lm.add(index++,s);
				}
				listBTDevices.setModel(lm);
			}
		});
		btnRefreshBTD.setBounds(10, 188, 89, 23);
		panel.add(btnRefreshBTD);
				
		JLabel lblConnectionstateNxt = new JLabel("Connectionstate NXT:");
		lblConnectionstateNxt.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblConnectionstateNxt.setBounds(10, 222, 113, 14);
		panel.add(lblConnectionstateNxt);
		
		final JLabel lblConnectedNXT = new JLabel("Disconnected");
		lblConnectedNXT.setForeground(Color.RED);
		lblConnectedNXT.setBounds(125, 222, 97, 14);
		panel.add(lblConnectedNXT);
		
		JLabel lblConnectionstateCam = new JLabel("Connectionstate Cam:");
		lblConnectionstateCam.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblConnectionstateCam.setForeground(new Color(0, 0, 0));
		lblConnectionstateCam.setBounds(10, 247, 113, 14);
		panel.add(lblConnectionstateCam);
		
		lblConnectedCam = new JLabel("Disconnected");
		lblConnectedCam.setForeground(Color.RED);
		lblConnectedCam.setBounds(125, 247, 97, 14);
		panel.add(lblConnectedCam);
		
		final JButton btnConnectToBT = new JButton("Connect");
		btnConnectToBT.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (btnConnectToBT.getText().equals("Connect")) {
					if (btm.connectNXTTo((String) listBTDevices.getSelectedValue())) {
						lblConnectedNXT.setText("Connected");
						lblConnectedNXT.setForeground(Color.green);
						btnConnectToBT.setText("Disconnect");
					}
				} else {
					btm.disconnectNXT(true);
					lblConnectedNXT.setText("Disconnected");
					lblConnectedNXT.setForeground(Color.red);
					btnConnectToBT.setText("Connect");
				}
			}
		});
		btnConnectToBT.setBounds(125, 188, 112, 23);
		panel.add(btnConnectToBT);
		
		JButton btnShutdownNxt = new JButton("Shutdown NXT");
		btnShutdownNxt.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnShutdownNxt.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(btnConnectToBT.getText().equals("Disconnect")){
					btm.sendCommandToNXT(StationCommands.NXT_SHUTDOWN);
					btm.disconnectNXT(false);
					lblConnectedNXT.setText("Disconnected");
					lblConnectedNXT.setForeground(Color.red);
					btnConnectToBT.setText("Connect");
				}
			}
		});
		btnShutdownNxt.setBounds(10, 267, 150, 23);
		panel.add(btnShutdownNxt);
		
		JPanel panelNXTStatus = new JPanel();
		panelNXTStatus.setBounds(10, 301, 372, 241);
		panel.add(panelNXTStatus);
		
		JLabel lblSignalstrenght = new JLabel("Signalstrenght");
		lblSignalstrenght.setBounds(10, 49, 69, 14);
		lblSignalstrenght.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		JLabel lblNxtStatusif = new JLabel("NXT Status (if connected)");
		lblNxtStatusif.setBounds(10, 24, 153, 14);
		lblNxtStatusif.setFont(new Font("Tahoma", Font.BOLD, 11));
		
		sliderSignalStrenght = new JSlider();
		sliderSignalStrenght.setFont(new Font("Tahoma", Font.PLAIN, 11));
		sliderSignalStrenght.setBounds(162, 45, 211, 47);
		sliderSignalStrenght.setPaintLabels(true);
		sliderSignalStrenght.setMinorTickSpacing(25);
		sliderSignalStrenght.setValue(0);
		sliderSignalStrenght.setMaximum(255);
		sliderSignalStrenght.setMajorTickSpacing(50);
		sliderSignalStrenght.setPaintTicks(true);
		
		JLabel lblBatteryvoltage = new JLabel("Batteryvoltage [V]:");
		lblBatteryvoltage.setBounds(10, 99, 93, 14);
		lblBatteryvoltage.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		lblBatteryvar = new JLabel("-----");
		lblBatteryvar.setBounds(317, 99, 46, 14);
		lblBatteryvar.setHorizontalAlignment(SwingConstants.RIGHT);
		
		lblSpeedvar = new JLabel("-----");
		lblSpeedvar.setBounds(317, 119, 46, 14);
		lblSpeedvar.setHorizontalAlignment(SwingConstants.RIGHT);
		
		lblDistancevar = new JLabel("-----");
		lblDistancevar.setBounds(317, 139, 46, 14);
		lblDistancevar.setHorizontalAlignment(SwingConstants.RIGHT);
		
		JLabel lblSpeed = new JLabel("Actual Speed [cm/s]:");
		lblSpeed.setBounds(10, 119, 113, 14);
		lblSpeed.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		JLabel lblDistance = new JLabel("Distance to target [cm]:");
		lblDistance.setBounds(10, 139, 121, 14);
		lblDistance.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		JLabel lblLightIntensity = new JLabel("Light intensity");
		lblLightIntensity.setBounds(10, 171, 97, 14);
		lblLightIntensity.setFont(new Font("Tahoma", Font.PLAIN, 11));
		
		sliderLightIntensity = new JSlider();
		sliderLightIntensity.setBounds(162, 164, 211, 44);
		sliderLightIntensity.setFont(new Font("Tahoma", Font.PLAIN, 11));
		sliderLightIntensity.setValue(0);
		sliderLightIntensity.setPaintTicks(true);
		sliderLightIntensity.setPaintLabels(true);
		sliderLightIntensity.setMinorTickSpacing(10);
		sliderLightIntensity.setMajorTickSpacing(20);
		panelNXTStatus.setLayout(null);
		panelNXTStatus.add(lblSignalstrenght);
		panelNXTStatus.add(lblNxtStatusif);
		panelNXTStatus.add(sliderSignalStrenght);
		panelNXTStatus.add(lblBatteryvoltage);
		panelNXTStatus.add(lblBatteryvar);
		panelNXTStatus.add(lblSpeedvar);
		panelNXTStatus.add(lblDistancevar);
		panelNXTStatus.add(lblSpeed);
		panelNXTStatus.add(lblDistance);
		panelNXTStatus.add(lblLightIntensity);
		panelNXTStatus.add(sliderLightIntensity);
		
		final JButton btnFloodlightOnOff = new JButton("Activate Floodlight");
		btnFloodlightOnOff.setBounds(10, 207, 150, 23);
		panelNXTStatus.add(btnFloodlightOnOff);
		btnFloodlightOnOff.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(btm.isConnectedToNXT()){
					if (btnFloodlightOnOff.getText().equals("Activate Floodlight")) {
						btm.sendCommandToNXT(StationCommands.ACTIVATE_FLOODLIGHT);
						btnFloodlightOnOff.setText("Deactivate Floodlight");
					} else {
						btm.sendCommandToNXT(StationCommands.DEACTIVATE_FLOODLIGHT);
						btnFloodlightOnOff.setText("Activate Floodlight");
					}
				}
			}
		});
		btnFloodlightOnOff.setFont(new Font("Tahoma", Font.PLAIN, 11));
	}
	
	private class RoboKeyDispatcher implements KeyEventDispatcher {
	    
		private BluetoothManager btm;
		private ArrayList<Character> fireList = new ArrayList<Character>();
		
		public void setBTM(BluetoothManager btm){
			this.btm = btm;
		}
		
		@Override
	    public boolean dispatchKeyEvent(KeyEvent e) {
	        if (e.getID() == KeyEvent.KEY_PRESSED) {
	        	if(!fireList.contains(e.getKeyChar()) && btm.isConnectedToNXT()){
	        		fireList.add(e.getKeyChar());
	        		switch (e.getKeyChar()) {
					case 'w':
						btm.sendCommandToNXT(StationCommands.START_MOVE_FORWARD);
						break;
					case 'a':
						btm.sendCommandToNXT(StationCommands.START_TURN_LEFT);
						break;
					case 's':
						btm.sendCommandToNXT(StationCommands.START_MOVE_BACKWARD);
						break;
					case 'd':
						btm.sendCommandToNXT(StationCommands.START_TURN_RIGHT);
						break;
					case 'f':
						btm.sendCommandToNXT(StationCommands.FIRE_CANNON);
					default:
						break;
					}
	        	}
	        } else if (e.getID() == KeyEvent.KEY_RELEASED) {
	        	if(fireList.contains(e.getKeyChar()) && btm.isConnectedToNXT()){
	        		fireList.remove(fireList.indexOf(e.getKeyChar()));
	        		switch (e.getKeyChar()) {
					case 'w':
						btm.sendCommandToNXT(StationCommands.STOP_MOVE_FORWARD);
						break;
					case 'a':
						btm.sendCommandToNXT(StationCommands.STOP_TURN_LEFT);
						break;
					case 's':
						btm.sendCommandToNXT(StationCommands.STOP_MOVE_BACKWARD);
						break;
					case 'd':
						btm.sendCommandToNXT(StationCommands.STOP_TURN_RIGHT);
						break;
					default:
						break;
					}
	        	}
	        } 
	        return false;
	    }
	}
}
